#include "KRuntime.h"
#include "KStream.h"
#include "KFile.h"

namespace krt
{
	void ForceDirectory(const char *dir)
	{
		char tmp[MAX_PATH];

		for(size_t i = 0; ; ++i)
		{
			switch(dir[i])
			{
			case PATH_DELIMITER:
			case 0:
				tmp[i] = 0;
				_mkdir(tmp);
				if (0 == dir[i])
					return;
				break;
			default:
				break;
			}
			tmp[i] = dir[i];
		}       
	}

	FileStream::FileStream():m_hFile(NULL)
	{

	}

	FileStream::~FileStream()
	{
		close();
	}

	BOOL FileStream::open(PCSTR FileName, FileMode mode)
	{
		close();

		const char* fm;

		switch(mode)
		{
		case fmOpenRead:
			fm = "rb";
			break;
		case fmOpenReadWrite:
			fm = "rb+";
			break;
		case fmCreate:
			fm = "wb+";
			break;
		default:
			return false;
		}

		return (NULL != (m_hFile = fopen(FileName, fm)));
	}

	BOOL FileStream::open(PCWSTR FileName, FileMode mode)
	{
		close();

		const wchar_t* fm;

		switch(mode)
		{
		case fmOpenRead:
			fm = L"rb";
			break;
		case fmOpenReadWrite:
			fm = L"rb+";
			break;
		case fmCreate:
			fm = L"wb+";
			break;
		default:
			return false;
		}

		return (NULL != (m_hFile = _wfopen(FileName, fm)));
	}

	void FileStream::close()
	{
		if (m_hFile)
		{
			fclose(m_hFile);
			m_hFile = NULL;
		}
	}

	void FileStream::SetEnd()
	{
#ifdef _WINDOWS
		::SetEndOfFile(m_hFile);
#endif	
	}

	stream::size_type FileStream::seek(offset_type offset, SeekOrigin origin)
	{
		_fseeki64(m_hFile, offset, origin);
		return (size_t)_ftelli64(m_hFile);
	}

	size_t FileStream::read(void* buf, size_t BufSize)
	{
		return fread(buf, 1, BufSize, m_hFile);
	}

	size_t FileStream::write(const void* buf, size_t BufSize)
	{
		return fwrite(buf, 1, BufSize, m_hFile);
	}
}